package scatter.common.rest.service;

import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import scatter.common.pojo.form.BasePageQueryForm;
import scatter.common.pojo.po.BasePo;
import scatter.common.rest.dataconstraint.DataConstraintService;
import scatter.common.rest.mapstruct.IBaseQueryFormMapStruct;
import scatter.common.rest.tools.StringTool;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;

/**
 * 查询基础父接口
 * Created by yangwei
 * Created at 2021/1/5 9:47
 */
public interface IBaseQueryFormService<Po,QueryForm> extends IBaseService<Po> {

    IBaseQueryFormMapStruct<Po,QueryForm> getQueryFormMapStruct();

    /**
     * 数据范围约束服务
     * @return
     */
    DataConstraintService getQueryDataConstraintService();

    /**
     * 查询前构造查询条件
     * @param queryWrapper
     * @return
     */
    default QueryWrapper<Po> prepareQueryFormQueryWrapper(QueryWrapper<Po> queryWrapper,QueryForm queryForm){

        return queryWrapper;
    }

    /**
     * baomidou不支持 or连接，这里手动转一下
     * issue https://github.com/baomidou/mybatis-plus/issues/3418
     * 该方法的初衷是拼接or使用，主要用户公共字段包含
     * @param queryWrapper
     * @return
     */
    default QueryWrapper<Po> convertEntityConditionToWrapper(QueryWrapper<Po> queryWrapper) {
        Po entity = queryWrapper.getEntity();
        if (entity == null) {
            return queryWrapper;
        }
        queryWrapper.setEntity(null);
        Field[] fields = ReflectUtil.getFields(entity.getClass());
        for (Field field : fields) {
            Object fieldValue = ReflectUtil.getFieldValue(entity, field);
            if (fieldValue != null && !Modifier.isStatic(field.getModifiers())) {
                queryWrapper.eq(StringTool.humpToLine(field.getName()), fieldValue);
            }
        }
        return queryWrapper;
    }

    /**
     * 不分页查询 考虑数据范围约束条件
     * @param queryForm
     * @return
     */
    default List<Po> list(QueryForm queryForm) {
        return list(queryForm,true);
    }
    /**
     * 不分页查询，
     * @param queryForm
     * @param dataConstraint 是否考虑数据范围约束条件
     * @return
     */
    default List<Po> list(QueryForm queryForm,boolean dataConstraint) {
        return list(getQueryWrapper(queryForm,dataConstraint));
    }
    /**
     * 分页查询
     * @param pageQueryForm
     * @return
     */
    default Page<Po> listPage(QueryForm pageQueryForm) {
        return listPage(pageQueryForm,true);
    }
    /**
     * 分页查询
     * @param pageQueryForm
     * @return
     */
    default Page<Po> listPage(QueryForm pageQueryForm,boolean dataConstraint) {
        Page pageQuery = new Page(((BasePageQueryForm) pageQueryForm).getCurrent(), ((BasePageQueryForm) pageQueryForm).getSize());
        return page(pageQuery,getQueryWrapper(pageQueryForm,dataConstraint));
    }
    /**
     * 根据表单组装查询条件
     * @param queryForm
     * @param dataConstraint 是否考虑数据范围约束
     * @return
     */
    default QueryWrapper<Po> getQueryWrapper(QueryForm queryForm,boolean dataConstraint) {
        Po po = getQueryFormMapStruct().queryFormToPo(queryForm);
        QueryWrapper<Po> queryWrapper = Wrappers.query(po);
        annotationSupportQueryWrapper(queryWrapper, queryForm);
        // 数据范围约束
        if (dataConstraint) {
            getQueryDataConstraintService().dataConstraint(queryWrapper);
        }
        prepareQueryFormQueryWrapper(queryWrapper,queryForm);
        queryWrapper.orderByAsc(BasePo.COLUMN_ID);
        return queryWrapper;
    }
    /**
     * 根据表单组装查询条件
     * @param queryForm
     * @return
     */
    default QueryWrapper<Po> getQueryWrapper(QueryForm queryForm) {
        return getQueryWrapper(queryForm,true);
    }


}
